package com.topofstack.flp.managers;

import java.util.Date;

import android.content.Context;
import android.content.SharedPreferences;

public class FLPPreferenceManager {
	Context context;
	
	final static String FLP_PREFS = "FLP_PREFS";
	
	final static String NUM_TRIES = "NUM_TRIES";
	final static String APP_LOCKED = "APP_LOCKED";
	
	final static String CONFIG_INTERVAL = "CONFIG_INTERVAL";
	final static String CONFIG_CHANCE = "CONFIG_CHANCE";
	final static String CONFIG_LOCK = "CONFIG_LOCK";
	
	final static String LAST_TRY = "LAST_TRY";
	final static String PASS = "PASS";
	
	final static String INTERNAL_FIRST_RUN = "INTERNAL_FIRST_RUN";
	
	final static String LOGIN_ERROR = "Wrong code";
	final static String LOCKED = "Application access has been locked. Please try again in %d seconds.";
	final static String EARLY = "Please try again in %d seconds time.";
	final static String TRY_AGAIN = "Please try again. %d more attempts are allowed.";
	
	public FLPPreferenceManager(Context c){
		this.context = c;
	}
	
	private int getIntValue(String key, int defValue){
		SharedPreferences prefs = context.getSharedPreferences(FLP_PREFS, 0);
		return prefs.getInt(key, defValue);
	}
	
	private String getStringValue(String key, String defValue){
		SharedPreferences prefs = context.getSharedPreferences(FLP_PREFS, 0);
		return prefs.getString(key, defValue);
	}
	
	private Date getDateValue(String key){
		SharedPreferences prefs = context.getSharedPreferences(FLP_PREFS, 0);
		String dateString = prefs.getString(key, null);
		if(dateString == null){
			return null;
		}
		return new Date(dateString);
	}
	
	private void setIntValue(String key, int value){
		SharedPreferences prefs = context.getSharedPreferences(FLP_PREFS, 0);
		SharedPreferences.Editor editor = prefs.edit();
		editor.putInt(key, value);
		editor.commit();
	}
	
	private void setStringValue(String key, String value){
		SharedPreferences prefs = context.getSharedPreferences(FLP_PREFS, 0);
		SharedPreferences.Editor editor = prefs.edit();
		editor.putString(key, value);
		editor.commit();
	}
	
	private void setDateValue(String key, Date value){
		SharedPreferences prefs = context.getSharedPreferences(FLP_PREFS, 0);
		SharedPreferences.Editor editor = prefs.edit();
		editor.putString(key, value.toGMTString());
		editor.commit();
	}
	
	private int timeIntervalSince(Date date){
		Date now = new Date();
		int seconds = (int)((now.getTime()-date.getTime())/1000);
		return seconds;
	}
	
	public int getNumTries(){
		return getIntValue(NUM_TRIES, 0);
	}
	
	public void increaseNumTries(){
		int tries = this.getNumTries();
		tries++;
		setIntValue(NUM_TRIES, tries);
	}
	
	public void resetNumTries(){
		setIntValue(NUM_TRIES, 0);
	}
	
	public int appLocked(){
		return getIntValue(APP_LOCKED, 0);
	}
	
	public void lockApp(){
		setIntValue(APP_LOCKED, 1);
	}
	
	public void unlockApp(){
		setIntValue(APP_LOCKED, 0);
	}
	
	public int internal_getFirstRun(){
		return getIntValue(INTERNAL_FIRST_RUN, 1);
	}
	
	public int config_getInterval(){
		return getIntValue(CONFIG_INTERVAL, 5);
	}
	
	public int config_getChance(){
		return getIntValue(CONFIG_CHANCE, 5);
	}
	
	public int config_getLock(){
		return getIntValue(CONFIG_LOCK, 60);
	}
	
	public void internal_setFirstRun(){
		setIntValue(INTERNAL_FIRST_RUN, 0);
	}
	
	public void config_setInterval(int n){
		setIntValue(CONFIG_INTERVAL, n);
	}
	
	public void config_setChance(int n){
		setIntValue(CONFIG_CHANCE, n);
	}
	
	public void config_setLock(int n){
		setIntValue(CONFIG_LOCK, n);
	}
	
	public Date getLastTryTime(){
		return getDateValue(LAST_TRY);
	}
	
	public void setLastTryTime(){
		setDateValue(LAST_TRY, new Date());
	}
	
	public int intervalSinceLastTry(){
		Date lastTry = getLastTryTime();
		if(lastTry == null){
			return Integer.MAX_VALUE;
		}
		else{
			return timeIntervalSince(lastTry);
		}
	}
	
	public int lockTimeRemaining(){
		int diff = this.intervalSinceLastTry();
		int lock = this.config_getLock();
		return (lock - diff);
	}
	
	public int retryTimeRemaining(){
		int diff = this.intervalSinceLastTry();
		int inter = this.config_getInterval();
		return (inter - diff);
	}
	
	public String getPass(){
		return getStringValue(PASS, null);
	}
	
	public void setPass(String pass){
		setStringValue(PASS, pass);
	}
	
	public String login(String pass){
		int applocked = this.appLocked();
		if(applocked == 1){
			int lock_remaining = this.lockTimeRemaining();
			if(lock_remaining > 0){
				return String.format(LOCKED, lock_remaining);
			}
			else{
				this.unlockApp();
			}
		}
		else{
			int retry_time_remaining = this.retryTimeRemaining();
			if(retry_time_remaining > 0){
				return String.format(EARLY, retry_time_remaining);
			}
			else{
				
			}
		}
		
		this.setLastTryTime();
		
		String challenge = this.getPass();
		if(challenge != null && challenge.equals(pass)){
			this.resetNumTries();
			return null;
		}
		
		this.increaseNumTries();
		int num_tries = this.getNumTries();
		int allowed_tries = this.config_getChance();
		if(num_tries >= allowed_tries){
			this.lockApp();
			this.resetNumTries();
		}
		
		int remaining_trials = allowed_tries - num_tries;
		
		return String.format(TRY_AGAIN, remaining_trials);
	}
}
